/**
 * @file schedule.c
 * @synopsis  调度otdr通道使用spi进行测量
 * @author wen wjcapple@163.com
 * @version 2.0
 * @date 2016-06-24
 */
#include <semaphore.h>
#include "pch_op.h"
#include "otdr_ch.h"
#include "hb_app.h"
#include "global.h"
#include "adpt_otdr.h"
#include "adpt_alarm.h"
#ifdef __cplusplus
extern "C" {
#endif
//用户点名测量，配置测量
extern struct _tagUsrOtdrTest usrOtdrTest;
//算法运行时当前的通道信息,开始测量的时候赋值，算法运行完毕清空
//spi 读取数据的缓冲区 spi 数据格式： fe 4B 2B fe 4B 2B
#define SPI_OP_SPACE_MS		1000 //spi设备的操作间隔  
extern _tagSpiDevCtrl spi_ctrl;
extern struct fpga_dev *fpga_device;
//记录线程信息
struct _tagThreadInfo *ptsk_testp_info;
extern struct _tagCHAlarmDis chAlarmDis;

//存放算法曲线的缓冲区
extern struct _tagOtdrTestCtrl otdrTestCtrl;
struct _tagParalleCtrl *paralleCtrlBuf;
struct _tagUsrOtdrTest *usrOtdrTestBuf_P;void echomsg(void *t)
{
	printf("destructor excuted in thread %u,param=%u\n",pthread_self(),((int *)t));
}
extern pthread_key_t key_ch;

/* --------------------------------------------------------------------------*/
/**
 * @synopsis  tsk_measur_p 并行otdr工作线程
 *
 * @param arg
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t initial_paralle_otdr()
{
	int32_t i,ret, ch_num_t;
	ch_num_t = otdrTestCtrl.ch_num;
	paralleCtrlBuf = malloc(sizeof( struct _tagParalleCtrl )*ch_num_t);
	if(paralleCtrlBuf == NULL)
		exit_self(errno,__FUNCTION__,__LINE__,"alloc paralle ctrl error");

	usrOtdrTestBuf_P= malloc(sizeof( struct _tagUsrOtdrTest )*ch_num_t);
	if(usrOtdrTestBuf_P == NULL)
		exit_self(errno,__FUNCTION__,__LINE__,"alloc usrOtdrTestBuf error");

	ptsk_testp_info = malloc(sizeof(struct _tagThreadInfo)*ch_num_t);
	if(ptsk_testp_info == NULL)
		exit_self(errno,__FUNCTION__,__LINE__,"alloc ptsk_testp_info error");

	memset(usrOtdrTestBuf_P, 0, sizeof(struct _tagUsrOtdrTest)*ch_num_t);
	memset(paralleCtrlBuf, 0, sizeof( struct _tagParalleCtrl )*ch_num_t);
	for(i = 0; i < ch_num_t;i++)
	{
		pthread_mutex_init(&paralleCtrlBuf[i].mutex_tsk, NULL);
		sem_init(&paralleCtrlBuf[i].sem_appoint, 0, 0);
		usrOtdrTestBuf_P[i].state = USR_OTDR_TEST_IDLE;
		ret = fpga_open("/dev/spidev3.0", &paralleCtrlBuf[i].device.fpga, 5000000);
		pthread_mutex_init(&paralleCtrlBuf[i].device.mutex_fpga, NULL);
		if(ret != 0)
		{
			PR_X("open spidev3.0 error ret %d \n",ret);
			exit_self(errno, __FUNCTION__, __LINE__, "can't open spidev3.0\0");
		}
	}

	pthread_key_create(&key_ch,echomsg);	
	
	return 0;
}
int32_t free_paralle_res()
{
	if(paralleCtrlBuf != NULL)
	{
		free(paralleCtrlBuf);
		paralleCtrlBuf = NULL;
	}
	if(usrOtdrTestBuf_P != NULL)
	{
		free(usrOtdrTestBuf_P);
		usrOtdrTestBuf_P = NULL;
	}
	if(ptsk_testp_info != NULL)
	{
		free(ptsk_testp_info);
		ptsk_testp_info = NULL;
	}
	return 0;
}
extern int32_t tsk_measur_p(void *arg);
int32_t create_paral_tsk(int32_t ch_num)
{

	int32_t i,ret;
	for(i = 0;i < ch_num;i++)
	{
		ptsk_testp_info[i].ch = i;
		ret = pthread_create(&ptsk_testp_info[i].tid,NULL, (void *)tsk_measur_p, &ptsk_testp_info[i]);
		if(ret != 0)
			exit_self(errno, __FUNCTION__, __LINE__, "creat tsk schedule erro\0");
			
	}
	return ret;
}
#ifdef __cplusplus
}
#endif
